<html>

<style>
    * {
        margin: 0;
    }

    #content {
        color: white;
        position: absolute;
        left: -20px;
        top: -10px;
        white-space: pre-wrap;
        height: 200px;
        overflow: auto;
    }
</style>

<script type="importmap">
	{
	  "imports": {
		"three": "../../three.js-r151/build/three.module.js",
		"three/addons/": "../../three.js-r151/examples/jsm/"
	  }
	}
</script>

<body>
    <div id="content">
        sprite不和图片合作了，和canvas合作会怎么样呢？
    </div>
    <div id="canvas"></div>

    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        // 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject
        import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
        // 引入CSS3渲染器CSS3DRenderer
        import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
        // 引入CSS3精灵模型对象CSS3DSprite
        import { CSS3DSprite } from 'three/addons/renderers/CSS3DRenderer.js';


        // 1. 必须创建的三大件
        // 1.1 三维场景Scene, 类似创建了个世界，三维世界
        const scene = new THREE.Scene();
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        const material = new THREE.MeshBasicMaterial({ color: 'yellow' });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        // 添加辅助坐标系
        const axesHelper = new THREE.AxesHelper(5);
        scene.add(axesHelper);

        // 1.2 相机
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(3, 3, 3)

        // 1.3 渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        let canvasDom = document.getElementById("canvas");
        canvasDom.appendChild(renderer.domElement);

        new OrbitControls(camera, canvasDom);

        // 3. sprite & canvas
        // 生成一个canvas对象，标注文字为参数name
        function createCanvas(name) {
            /**
             * 创建一个canvas对象，绘制几何图案或添加文字
             */
            const canvas = document.createElement("canvas");
            const arr = name.split(""); //分割为单独字符串
            let num = 0;
            const reg = /[\u4e00-\u9fa5]/;
            for (let i = 0; i < arr.length; i++) {
                if (reg.test(arr[i])) { //判断是不是汉字
                    num += 1;
                } else {
                    num += 0.5; //英文字母或数字累加0.5
                }
            }
            // 根据字符串符号类型和数量、文字font-size大小来设置canvas画布宽高度
            const h = 80; //根据渲染像素大小设置，过大性能差，过小不清晰
            const w = h + num * 32;
            canvas.width = w;
            canvas.height = h;
            const h1 = h * 0.8;
            const c = canvas.getContext('2d');
            // 定义轮廓颜色，黑色半透明
            c.fillStyle = "green";
            // 绘制半圆+矩形轮廓
            const R = h1 / 2;
            c.arc(R, R, R, -Math.PI / 2, Math.PI / 2, true); //顺时针半圆
            c.arc(w - R, R, R, Math.PI / 2, -Math.PI / 2, true); //顺时针半圆
            c.fill();
            // 绘制箭头
            c.beginPath();
            const h2 = h - h1;
            c.moveTo(w / 2 - h2 * 0.6, h1);
            c.lineTo(w / 2 + h2 * 0.6, h1);
            c.lineTo(w / 2, h);
            c.fill();
            // 文字
            c.beginPath();
            c.translate(w / 2, h1 / 2);
            c.fillStyle = "#ffffff"; //文本填充颜色
            c.font = "normal 32px 宋体"; //字体样式设置
            c.textBaseline = "middle"; //文本与fillText定义的纵坐标
            c.textAlign = "center"; //文本居中(以fillText定义的横坐标)
            c.fillText(name, 0, 0);
            return canvas;
        }
        const canvas = createCanvas('设备A')

        // const texture = new THREE.TextureLoader().load("./warning.png");

        // canvas画布作为CanvasTexture的参数创建一个纹理对象
        // 本质上你可以理解为CanvasTexture读取参数canvas画布上的像素值
        const texture = new THREE.CanvasTexture(canvas);
        const spriteMaterial = new THREE.SpriteMaterial({
            map: texture,
            side: THREE.DoubleSide,
        });
        const sprite = new THREE.Sprite(spriteMaterial);
        scene.add(sprite)
        sprite.position.set(0, 1.5, 0)
        cube.scale.set(2, 2, 2)


        function render() {
            renderer.render(scene, camera);
            requestAnimationFrame(render)
        }
        render();

        // 画布跟随窗口变化
        window.onresize = function () {
            const width = window.innerWidth;
            const height = window.innerHeight;
            // cnavas画布宽高度重新设置
            renderer.setSize(width, height);
            camera.aspect = width / height;
            camera.updateProjectionMatrix();
        };


    </script>
</body>

</html>